use std::process::Command;
use serde::{Serialize, Deserialize};
use tauri::command;

#[derive(Debug, Serialize, Deserialize)]
pub struct MirrorInfo {
    name: String,
    url: String,
    latency: Option<u32>,
}

#[command]
pub async fn get_system_info() -> Result<String, String> {
    let os_info = if cfg!(target_os = "linux") {
        let output = Command::new("lsb_release")
            .args(["-ds"])
            .output()
            .map_err(|e| e.to_string())?;
        String::from_utf8_lossy(&output.stdout).trim().to_string()
    } else {
        "Unsupported OS".to_string()
    };
    Ok(os_info)
}

#[command]
pub async fn switch_mirror(mirror_url: String) -> Result<(), String> {
    let distro = distro::detect_distro()
        .ok_or("无法检测发行版".to_string())?;

    match distro.as_str() {
        "ubuntu" | "debian" => {
            Command::new("sudo")
                .args(["cp", "/etc/apt/sources.list", "/etc/apt/sources.list.bak"])
                .status()
                .map_err(|e| e.to_string())?;
            
            Command::new("sudo")
                .args(["sed", "-i", &format!("s|http://.*/|{}|g", mirror_url), "/etc/apt/sources.list"])
                .status()
                .map_err(|e| e.to_string())?;
        }
        "centos" | "fedora" => {
            Command::new("sudo")
                .args(["sed", "-i", &format!("s|baseurl=.*|baseurl={}|g", mirror_url), "/etc/yum.repos.d/*.repo"])
                .status()
                .map_err(|e| e.to_string())?;
        }
        _ => return Err("不支持的发行版".to_string()),
    }
    Ok(())
}

#[command]
pub async fn test_mirror_speed(mirror_url: String) -> Result<u32, String> {
    let latency = Command::new("ping")
        .args(["-c", "4", &mirror_url])
        .output()
        .map_err(|e| e.to_string())?;

    let output = String::from_utf8_lossy(&latency.stdout);
    let avg_ping = output
        .lines()
        .find(|l| l.contains("avg"))
        .and_then(|l| l.split("/").nth(4).and_then(|s| s.parse().ok()))
        .unwrap_or(0);

    Ok(avg_ping)
}